#include <cstdlib>
#include <iostream>
#include "NclStateMachine.h"
#include "structs/stateChanged.h"


// nclStateMachine Method Implementing
NclStateMachine::NclStateMachine():m_state_id(SLEEPING),m_previus_state_id(SLEEPING)
{
	// starts in sleeping state!
	m_current_state = new Sleeping();
}

void NclStateMachine::setState(State* s)
{
	m_current_state = s;
}	

void NclStateMachine::sleeping()
{
	m_previus_state_id=m_state_id;
	m_current_state->sleeping(this);
	m_state_id=SLEEPING;
}
void NclStateMachine::occurring()
{
	m_previus_state_id=m_state_id;
	m_current_state->occurring(this);
	m_state_id=OCCURRING;
}
void NclStateMachine::paused()
{
	m_previus_state_id=m_state_id;
	m_current_state->paused(this);
	m_state_id=PAUSED;
}
STATE NclStateMachine::getState()
{
	return m_state_id;
}
STATE NclStateMachine::getPreviousState()
{
	return m_previus_state_id;
}

// Sleeping Method Implementing
void Sleeping::occurring(NclStateMachine* nclStateWrapper)
{
	std::cout << "Setting Occurring" << std::endl;
	nclStateWrapper->setState(new Occurring());
	delete this;
	
}

// Occurring Method Implementing
void Occurring::sleeping(NclStateMachine* nclStateWrapper)
{
	std::cout << "Setting Sleeping" << std::endl;
	nclStateWrapper->setState(new Sleeping());
	delete this;

}
void Occurring::paused(NclStateMachine* nclStateWrapper)
{
	std::cout << "Setting Paused" << std::endl;
	nclStateWrapper->setState(new Paused());
	delete this;
}
// Paused Method Implementing
void Paused::sleeping(NclStateMachine* nclStateWrapper)
{
	std::cout << "Setting Sleeping" << std::endl;
	nclStateWrapper->setState(new Sleeping());
	delete this;
}
void Paused::occurring(NclStateMachine* nclStateWrapper)
{
	std::cout << "Setting Occurring" << std::endl;
	nclStateWrapper->setState(new Occurring());
	delete this;	
}

void NclStateManager::notifyChange()
{
	stateChanged s;
	s.element=idElement;
	s.event= event.get();
	s.transition = transition.get();

	std::cout << "Notifying:: element:" << s.element << " - transition:" << transition.getTransitionString(s.transition) << " - event:" << getEventString(s.event) << std::endl;

	//NclSignalManager* m_signal = &NclSignalManager::getInstance();
	m_signal->send(s);
}

#ifdef TEST_NCL_STATE_MACHINE
int main()
{
	const int idElement=1;
	const int iRepetitions=3;	
  	NclStateManager manageState(idElement,iRepetitions);

	int i;
	ACTION actionNumber;

	while (1)
	{
	    std::cout << "Enter 0(start)/1(stop)/2(pause)/3(resume)/4(abort)/5(get state)/other(bye): ";
	    std::cin >> i;

		actionNumber = (ACTION)i;
		if(actionNumber > ACTION_LENGTH)
		{
			std::exit(0);
		}
		else if(actionNumber == ACTION_LENGTH)
		{
			std::cout << "state:" << manageState.getStateString(manageState.getState()) << std::endl;
		}
		else
		{
			// call function pointers		
	    		//(manageState.*pExecuteAction[actionNumber])();
	    		manageState.executeAction(actionNumber);
			std::cout << "occurrences:" << manageState.getOccurrences() << std::endl;
			std::cout << "repetitions:" << manageState.getRepetitions() << std::endl;
			
		}
	}

}
#endif
